package com.tt.expandablecalendar.ui.widget.calendar;

import java.util.Calendar;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.tt.expandablecalendar.R;
import com.tt.expandablecalendar.ui.widget.calendar.CalendarCard.OnCalendarChangeListener;
import com.tt.expandablecalendar.ui.widget.calendar.CalendarCard.YearAndMonth;
import com.tt.expandablecalendar.ui.widget.calendar.CalendarGridViewAdapter.OnDaySelectListener;

/**
 * 日历总体控件 <功能简述> <Br>
 * <功能详细描述> <Br>
 * 
 * @author kysonX http://www.hizhaohui.cn/
 */
public class CalendarCardView extends RelativeLayout {
    // date split... why english ? because my input got a crash
    public static final char DATE_SPLIT = '-';

    private boolean isAniming;

    // 是否展开状态
    private boolean mIsExpand = true;
    // 日历高度
    private int mCalendarHeight;

    private Context mContext;
    private TextView mLeftBtn;
    private TextView mRightBtn;
    private TextView mBackBtn;
    private TextView mDateTextView;
    private CalendarCard mCalendarCard;

    public CalendarCardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        init();
    }

    public CalendarCardView(Context context) {
        super(context);
        this.mContext = context;
        init();
    }

    private void init() {
        initView();
        initEvent();
    }

    private void initView() {
        inflate(mContext, R.layout.widget_common_calendar_view, this);
        mLeftBtn = (TextView) this
                .findViewById(R.id.widget_common_calendar_view_left);
        mRightBtn = (TextView) this
                .findViewById(R.id.widget_common_calendar_view_right);
        mBackBtn = (TextView) this
                .findViewById(R.id.widget_common_calendar_view_back);
        mDateTextView = (TextView) this
                .findViewById(R.id.widget_common_calendar_view_date);
        mCalendarCard = (CalendarCard) this
                .findViewById(R.id.widget_common_calendar_view_calendarcard);
    }

    private void initEvent() {
        mLeftBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mCalendarCard.toBeforeCalendar();
            }
        });
        mRightBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mCalendarCard.toAfterCalendar();
            }
        });

        mBackBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mCalendarCard.setCurrentCalendar(Calendar.getInstance());
            }
        });
        mCalendarCard
                .setOnCalendarChangeListener(new OnCalendarChangeListener() {

                    @Override
                    public void onCalendarChange(YearAndMonth ym) {
                        mDateTextView.setText(String.valueOf(ym.year)
                                + DATE_SPLIT + String.valueOf(ym.month + 1));
                        // 这里因为数据是变化的，所以高度也会变化
                        mCalendarCard.getLayoutParams().height = LayoutParams.FILL_PARENT;
                        mCalendarHeight = mCalendarCard.getHeight();
                    }
                });
        mDateTextView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (isAniming) {
                    return;
                }
                if (mIsExpand) {
                    onPackup();
                } else {
                    onExpand();
                }
            }
        });
    }

    /**
     * 收起日历 <功能简述>
     */
    private void onPackup() {
        mIsExpand = false;
        mLeftBtn.setEnabled(false);
        mRightBtn.setEnabled(false);
        mBackBtn.setEnabled(false);
        // 收起日历之前先记下日历高度
        mCalendarHeight = mCalendarCard.getHeight();
        performAnim();
    }

    /**
     * 展开日历 <功能简述>
     */
    private void onExpand() {
        mIsExpand = true;
        mLeftBtn.setEnabled(true);
        mRightBtn.setEnabled(true);
        mBackBtn.setEnabled(true);
        performAnim();
    }

    private void performAnim() {
        performArrowAnim();
        performTodayAnim();
        performCalAnim();
    }

    public static final long ANIM_DURATION = 300;

    public static final int TRANS_X = 20;

    /**
     * 左右箭头的动画 <功能简述>
     */
    private void performArrowAnim() {
        AnimatorSet allSet = new AnimatorSet();
        ObjectAnimator leftTrans = mIsExpand ? ObjectAnimator.ofFloat(mLeftBtn,
                "translationX", -TRANS_X, 0) : ObjectAnimator.ofFloat(mLeftBtn,
                "translationX", 0, -TRANS_X);
        ObjectAnimator leftAlpha = mIsExpand ? ObjectAnimator.ofFloat(mLeftBtn,
                "alpha", 0f, 1f) : ObjectAnimator.ofFloat(mLeftBtn, "alpha",
                1f, 0f);
        ObjectAnimator rightTrans = mIsExpand ? ObjectAnimator.ofFloat(
                mRightBtn, "translationX", TRANS_X, 0) : ObjectAnimator
                .ofFloat(mRightBtn, "translationX", 0, TRANS_X);
        ObjectAnimator rightAlpha = mIsExpand ? ObjectAnimator.ofFloat(
                mRightBtn, "alpha", 0f, 1f) : ObjectAnimator.ofFloat(mRightBtn,
                "alpha", 1f, 0f);
        allSet.playTogether(leftTrans, leftAlpha, rightTrans, rightAlpha);
        allSet.setInterpolator(new DecelerateInterpolator());
        allSet.setDuration(ANIM_DURATION);
        allSet.start();
    }

    /**
     * 回到今天的按钮 <功能简述>
     */
    private void performTodayAnim() {
        ObjectAnimator todayAnim;
        if (mIsExpand) {
            todayAnim = ObjectAnimator.ofFloat(mBackBtn, "alpha", 0f, 1f);
        } else {
            todayAnim = ObjectAnimator.ofFloat(mBackBtn, "alpha", 1f, 0f);
        }
        todayAnim.setDuration(ANIM_DURATION).start();
    }

    /**
     * 日历的动画 <功能简述>
     */
    private void performCalAnim() {
        ValueAnimator valueAnimator = mIsExpand ? ValueAnimator.ofInt(0,
                mCalendarHeight) : ValueAnimator.ofInt(
                mCalendarCard.getHeight(), 0);

        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                int currentValue = (Integer) animator.getAnimatedValue();
                mCalendarCard.getLayoutParams().height = currentValue;
                mCalendarCard.requestLayout();
            }
        });
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addListener(new AnimatorListener() {

            @Override
            public void onAnimationStart(Animator arg0) {
                isAniming = true;
            }

            @Override
            public void onAnimationRepeat(Animator arg0) {

            }

            @Override
            public void onAnimationEnd(Animator arg0) {
                isAniming = false;
            }

            @Override
            public void onAnimationCancel(Animator arg0) {
                isAniming = false;
            }
        });
        valueAnimator.setDuration(ANIM_DURATION).start();
    }

    /**
     * set listenr of selecting date <功能简述>
     * 
     * @param onDaySelectListener
     */
    public void setOnDaySelectListener(OnDaySelectListener onDaySelectListener) {
        mCalendarCard.setOnDaySelectListener(onDaySelectListener);
    }

    public Calendar getSelectedDate() {
        return mCalendarCard.getSelectedDate();
    }

    public void setCurrentDate(Calendar cal) {
        mCalendarCard.setCurrentCalendar(cal);
    }

}
